package data.service;

import com.sghd.common.utils.json.JsonUtils;
import data.dao.MysqlTemplate;
import data.entity.GameRecord;
import data.entity.PK;
import data.entity.RecordPropModify;
import data.entity.RecordSettleError;
import data.model.BasePlayer;
import data.model.PropType;
import game.model.DeskPlayer;
import game.model.GameResult;
import game.model.MGame;
import game.model.ReturnMsg;
import org.apache.commons.collections.MapUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import utils.http.HttpConfig;
import utils.http.HttpUtil;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author fank
 * @date 2018-08-18 14:49
 * @desc
 **/
@Component
public class DataService {
    private Logger logger = LoggerFactory.getLogger(getClass());
    @Autowired
    private MysqlTemplate mysqlTemplate;

    /**
     * 游戏数据结算
     * @param changeSource 货币更忙来源(1:游戏结算)
     * @param detail --> 道具详情（propID:propNum;propID:propNum）
     **/
    public void updatePlayerPropInfo(Long playerId, int gameId, Integer changeSource, String detail,
                                     long beforeMoney) throws Exception {
        Map<String, Object> json = new HashMap<>();
        json.put("action", "update");
        json.put("beforeMoney", beforeMoney);
        json.put("playerID", playerId);
        json.put("gameID", gameId);
        json.put("detail", detail);
        json.put("changeSource", changeSource);
        ReturnMsg rmsg = HttpUtil.sendData(json, HttpConfig.send_post, HttpConfig.encrypt_java, "hallServlet");
        json.clear();
        if (rmsg.getState() != 1) {
            throw new RuntimeException(rmsg.getInfo());
        }
    }


    /**
     * 进入游戏房间
     **/
    public boolean intoRoom(long playerId, int gameId, int roomId) {
        Map<String, Object> params = new HashMap<>();
        params.put("action", "intoRoom");
        params.put("playerID", playerId);
        params.put("gameID", gameId);
        params.put("roomID", roomId);
        ReturnMsg rmsg = new ReturnMsg();
        try {
            rmsg = HttpUtil.sendData(params, HttpConfig.send_post, HttpConfig.encrypt_java, "hallServlet");
            logger.debug("玩家[{}]进入房间", playerId);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
        params.clear();
        if (rmsg.getState() == 1) {
            return true;
        }
        return false;
    }


    /** 离开游戏房间 **/
    public void outRoom(long playerId, int gameId, int roomId) {
        Map<String, Object> params = new HashMap<>();
        params.put("action", "leaveRoom");
        params.put("playerID", playerId);
        params.put("gameID", gameId);
        params.put("roomID", roomId);
        try {
            HttpUtil.sendData(params, HttpConfig.send_post, HttpConfig.encrypt_java, "hallServlet");
            logger.debug("玩家[{}]离开房间", playerId);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
        params.clear();
    }

    public void intoDesk(long playerId, int gameId, int roomId, int deskId, int seatId) {
        Map<String, Object> params = new HashMap<>();
        params.put("action", "intoDesk");
        params.put("playerID", playerId);
        params.put("gameID", gameId);
        params.put("roomID", roomId);
        params.put("deskID", deskId);
        params.put("seatID", seatId);
        try {
            HttpUtil.sendData(params, HttpConfig.send_post, HttpConfig.encrypt_java, "hallServlet");
        } catch (Exception e) {
            e.printStackTrace();
        }
        params.clear();
    }

    /**
     * 获得玩家基础信息与辅助信息
     **/
    @SuppressWarnings("unchecked")
    public DeskPlayer getPlayeInfo(long playerId) throws Exception {
        Map<String, Object> params = new HashMap<>();
        params.put("action", "playerInfo");////基本信息
        params.put("playerID", playerId);
        ReturnMsg rmsg = null;
        try {
            rmsg = HttpUtil.sendData(params, HttpConfig.send_post, HttpConfig.no_encrypt_java, "hallServlet");
        } catch (Exception e) {
            logger.error("获取玩家[{}]基本信息发生未知错误！", playerId, e);
            throw e;
        }
        List<Map<String, Object>> datas = rmsg.getResult();
        if (datas == null || datas.isEmpty()) {
            logger.error("获取玩家[{}]基本信息失败！", playerId);
            return null;
        }
        Map<String, Object> data = datas.get(0);
        Map<String, Object> base = (Map<String, Object>) data.get("baseInfo");
        String nickName = MapUtils.getString(base, "nickName");
        String headUrl = MapUtils.getString(base, "headUrl");
        int playerSex = MapUtils.getIntValue(base, "playerSex");
        String presentation = MapUtils.getString(base, "presentation");
        Map<String, Object> assistJSON = MapUtils.getMap(data, "assistInfo");
        int vipLevel = MapUtils.getIntValue(assistJSON, "vipLevel");
        return new DeskPlayer(playerId, nickName, headUrl, playerSex, presentation, vipLevel);//基本信息
    }

    /**
     * 获取玩家背包
     * @param player
     */
    public void getBagInfo(BasePlayer player) throws Exception {
        long playerId = player.getPlayerId();
        //获取玩家背包信息
        Map<String, Object> params = new HashMap<>();
        params.put("action", "bagInfo");
        params.put("playerID", playerId);
        ReturnMsg rmsg = new ReturnMsg();
        try {
            rmsg = HttpUtil.sendData(params, HttpConfig.send_post, HttpConfig.no_encrypt_java, "hallServlet");
        } catch (Exception e) {
            logger.error("获取玩家[{}]背包发生未知错误！", playerId, e);
            throw e;
        }
        Map<String, Object> data = rmsg.getResult().get(0);
        Map<PropType, Long> bag = new HashMap<>();
        for (Map.Entry<String, Object> entry : data.entrySet()) {
            PropType type = PropType.valueOf(Integer.valueOf(entry.getKey()));
            bag.put(type, Long.parseLong(entry.getValue().toString()));
        }
        player.setBagInfo(bag);
    }

    /**
     * 检查token是否正确
     **/
    public boolean checkToken(long playerId, String token, String P, int platformId) {
        Map<String, Object> params = new HashMap<>();
        params.put("token", token);
        params.put("P", P);
        params.put("playerID", playerId);
        params.put("platformId", platformId);
        params.put("action", "analyseToken");
        ReturnMsg rmsg = new ReturnMsg();
        try {
            rmsg = HttpUtil.sendData(params, HttpConfig.send_post, HttpConfig.encrypt_java, "loginServlet");
        } catch (Exception e) {
            logger.error("token验证失败：{}", e.getMessage(), new Object[]{e});
        }
        params.clear();
        return rmsg.getState() == 1;
    }

    public void leaveDesk(long playerId, int gameId, int roomId, int deskId, int seatId, int type) {
        Map<String, Object> params = new HashMap<>();
        params.put("action", "leaveDesk");
        params.put("playerID", playerId);
        params.put("gameID", gameId);
        params.put("roomID", roomId);
        params.put("deskID", deskId);
        params.put("seatID", seatId);
        params.put("type", type);
        try {
            HttpUtil.sendData(params, HttpConfig.send_post, HttpConfig.encrypt_java, "hallServlet");
        } catch (Exception e) {
            e.printStackTrace();
        }
        params.clear();
    }

    public GameRecord getGameRecord(PK pk) {
        GameRecord record = mysqlTemplate.findById(pk, GameRecord.class);
        return record;
    }

    public void saveOrUpdate(GameRecord record) {
        mysqlTemplate.save(record);
    }
    /**
     * 普通旋转
     * */
    public boolean settleNormal(DeskPlayer player, int gameId, int roomId, int deskId, GameResult result, long change) throws Exception {
        long current = player.getMondey(PropType.GOLD);//当前金币
        //数据服结算
        if (change != 0) {
            updatePlayerPropInfo(player.getPlayerId(), gameId, 1, PropType.GOLD.getValue() + ":" + change + ";", current);
        }
        RecordPropModify record = new RecordPropModify();
        record.setRemark("得分:" + result.getTotalFen() + "@押注:" + result.getTotalBet() + "@免费:" + result.iscFree() + "@购买:" + result.getCost() + "@" + JsonUtils.object2String(result));
        record.setPlayerId(player.getPlayerId());
        record.setNickName(player.getNickName());
        record.setGameId(gameId);
        record.setRoomId(roomId);
        record.setDeskId(deskId);
        record.setSeatId(-1);
        record.setPropId(PropType.GOLD.getValue());
        record.setChangeNum(change);
        record.setChangeSource(1);
        record.setTaxNum(0l);
        record.setShowToPlayer("游戏结算：" + change);
        record.setCreateTime(new Date());
        mysqlTemplate.insert(record);
        return true;
    }

    public boolean settleMgame(DeskPlayer player, int gameId, int roomId, int deskId, MGame result) throws Exception {
        long totalFen = result.getTotalFen();
        long current = player.getMondey(PropType.GOLD);//当前金币
        //数据服结算
        if (totalFen != 0) {
            updatePlayerPropInfo(player.getPlayerId(), gameId, 1, PropType.GOLD.getValue() + ":" + totalFen + ";", current);
        }
        RecordPropModify record = new RecordPropModify();
        record.setRemark("得分(小游戏):" + totalFen + ",押注:" + result.getTotalBet() + ",类型:" + result.getType() + ",倍率/免费:"
                + result.getScope() + "@" + JsonUtils.object2String(result.getSequen()));
        record.setPlayerId(player.getPlayerId());
        record.setNickName(player.getNickName());
        record.setGameId(gameId);
        record.setRoomId(roomId);
        record.setDeskId(deskId);
        record.setSeatId(-1);
        record.setPropId(PropType.GOLD.getValue());
        record.setChangeNum(totalFen);
        record.setChangeSource(1);
        record.setTaxNum(0l);
        record.setShowToPlayer("小游戏结算：" + totalFen);
        record.setCreateTime(new Date());
        mysqlTemplate.insert(record);
        return true;
    }

    /**
     * 保存结算失败的数据
     * */
    public void settleError(DeskPlayer player, GameResult result, Throwable ex) {
        long change = result.getTotalFen() - result.getTotalBet();
        RecordSettleError error = new RecordSettleError();
        error.setChange(change);
        error.setPlayerId(player.getPlayerId());
        error.setName(player.getNickName());
        error.setResult(JsonUtils.object2String(result));
        error.setTotalBet(result.getTotalBet());
        error.setTotalFen(result.getTotalFen());
        error.setRemark("得分:" + result.getTotalFen() + "@押注:" + result.getTotalBet() + "@免费:" + result.iscFree() + "@" + JsonUtils.object2String(result));
        if (ex != null) {
            error.setException(ex.getMessage());
        }
        mysqlTemplate.insert(error);
    }

    /**
     * 保存小游戏结算失败的数据
     * */
    public void settleError(DeskPlayer player, MGame result, Throwable ex) {
        long change = result.getTotalFen();
        RecordSettleError error = new RecordSettleError();
        error.setChange(change);
        error.setPlayerId(player.getPlayerId());
        error.setName(player.getNickName());
        error.setResult(JsonUtils.object2String(result));
        error.setTotalBet(0);
        error.setTotalFen(result.getTotalFen());
        error.setRemark("得分(小游戏):" + result.getTotalFen() + "@押注:" + result.getTotalBet() + "@" + JsonUtils.object2String(result));
        if (ex != null) {
            error.setException(ex.getMessage());
        }
        mysqlTemplate.insert(error);
    }
}
